package com.sina.shop.manage.service.order;

import com.sina.shop.core.exception.client.DataException;
import com.sina.shop.core.exception.server.CreateException;
import com.sina.shop.core.exception.server.ResourceExistsException;
import com.sina.shop.core.exception.server.UpdateException;
import com.sina.shop.domain.order.Order;
import com.sina.shop.manage.dao.card.CardManageDao;
import com.sina.shop.manage.dao.order.OrderManageDao;
import com.sina.shop.service.ShopDataSourceService;
import com.sina.shop.util.Assert;
import com.sina.shop.util.ResultCode;
import com.sina.shop.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

import static com.sina.shop.service.ServiceConstant.SHOP_TX;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * 段浩杰   2018-01-12-16:31
 */
@Service("orderManageService")
public class OrderManageServiceImpl extends ShopDataSourceService implements OrderManageService {

    @Autowired
    @Qualifier("orderManageDao")
    private OrderManageDao orderManageDao;

    @Autowired
    @Qualifier("cardManageDao")
    private CardManageDao cardManageDao;

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public Order getOrderById(Long id) {
        return orderManageDao.get(Order.class, id);
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public int deleteOrder(Long id) throws DataException, UpdateException {
        Order order = orderManageDao.get(Order.class, id);
        Assert.assertNotNull(order, "Order[id=%s] not exists", order.getId());

        try {
            return orderManageDao.deleteOrder(id);
        } catch (DataAccessException e) {
            LOG.error(" {} delete Order error.", Order.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.READ_COMMITTED)
    public Order saveOrder(Order order) throws CreateException, ResourceExistsException, DataException {
        try {

            orderManageDao.save(order);
            orderManageDao.flush();
            return order;
        } catch (DataAccessException e) {
            LOG.error(" {} save Order error.", Order.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    @Override
    @Transactional(value = SHOP_TX, isolation = Isolation.REPEATABLE_READ)
    public Order updateOrder(Order order) throws UpdateException, DataException {
        Order o = orderManageDao.get(Order.class, order.getId());
        Assert.assertNotNull(o, "Order[id=%s] not exists", order.getId());

        try {
            o = updateOrderFiled(order, o);
            orderManageDao.flush();

            return o;
        } catch (DataAccessException e) {
            LOG.error(" {} update Order error.", Order.class, e);
            throw new UpdateException(ResultCode.dataAccessError, e.getMessage(), e);
        }
    }

    private Order updateOrderFiled(Order oldOrder, Order newOrder) {


        if (!StringUtils.isEmpty(oldOrder.getStatus())) {
            newOrder.setStatus(oldOrder.getStatus());
        }

        if (oldOrder.getPayTime() != null && newOrder.getPayTime() == null) {
            newOrder.setPayTime(oldOrder.getPayTime());
        }

        if (oldOrder.getPayTime() == null) {
            newOrder.setPayTime(null);
        }

        return newOrder;
    }

    @Override
    @Transactional(value = SHOP_TX, readOnly = true, isolation = Isolation.READ_COMMITTED)
    public List<Map<String, Object>> getOrderList(Order order, Long[] count) {

        //暂时废弃以账号查找的功能


        if (count != null && count.length > 0) {
            count[0] = orderManageDao.getOrderCount(order);
        }

        return orderManageDao.getOrderList(order);
    }
}
